package probe.sound.code;

import java.io.PrintStream;

public class Util {
  
  public static void printBits(PrintStream out, byte b) {
    for (int i = 8; i-- > 0;) {
      out.print( ((b & (0x1 << i)) == 0) ? "0" :"1" );
    }
  }
  
  public static byte doubleToByte(double value) {
    if (value >= 1) return (byte)127;
    if (value <= -1) return (byte)-128;
    double d_0_256 = (value + 1) * 256.0 / 2.0;
    int i_0_255 = (int)d_0_256;
    
    return (byte)(i_0_255 - 128);
  }
  
  public static int readInt4(byte[] buf, int offset, boolean littleEndian) {
    int ret = 0;
    
    if (littleEndian) {
      for (int i = 0; i < 4; i++) {
        ret |= (((int)buf[offset + i]) & 0xFF) << (8 * i);
      }
    } else {
      offset += 3;
      for (int i = 0; i < 4; i++) {
        ret |= (((int)buf[offset - i]) & 0xFF) << (8 * i);
      }
    }
    
    return ret;
  }
  
  public static void writeInt4(byte[] buf, int offset, boolean littleEndian, int value) {
    if (littleEndian) {
      for (int i = 0; i < 4; i++) {
        buf[offset + i] = (byte)(value & 0xFF);
        value >>= 8;
      }
    } else {
      offset += 3;
      for (int i = 0; i < 4; i++) {
        buf[offset - i] = (byte)(value & 0xFF);
        value >>= 8;
      }
    }
    
  }
  
  public static int readWord(byte[] buf, int offset, boolean littleEndian) {
    int ret = 0;
    
    if (littleEndian) {
      for (int i = 0; i < 2; i++) {
        ret |= (((int)buf[offset + i]) & 0xFF) << 8 * i;
      }
    } else {
      offset++;
      for (int i = 0; i < 2; i++) {
        ret |= (((int)buf[offset - i]) & 0xFF) << 8 * i;
      }
    }
    
    return ret;
  }
  
  public static void writeWord(byte[] buf, int offset, boolean littleEndian, int word) {
    int byte0 = (word >> (8 * 0)) & 0xFF;
    int byte1 = (word >> (8 * 1)) & 0xFF;
    
    if (littleEndian) {
      buf[offset + 0] = (byte)byte0;
      buf[offset + 1] = (byte)byte1;
    } else {
      buf[offset + 0] = (byte)byte1;
      buf[offset + 1] = (byte)byte0;
    }
  }
  
  public static final char[] CHIS16 = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8',
      '9', 'A', 'B', 'C', 'D', 'E', 'F' };
  
  public static String asHex(byte b) {
    StringBuilder sb = new StringBuilder( 2 );
    sb.append( CHIS16[(b >> 4) & (byte)15] );
    sb.append( CHIS16[b & (byte)15] );
    return sb.toString();
  }
  
  public static int toSignedWord(double value) {
    if (value >= 1) return 32767;
    if (value <= -1) return -32768;
    int ret = (int)((value + 1.0) * 32768.0);
    return ret - 32768;
  }
  
  public static double fromSignedWord(int signedWord) {
    double ret = signedWord;
    ret /= 32768.0;
    return ret;
  }
}
